import { U16, U8 } from "./codec";
import conn from "./conn";
import { addr, heat } from "./proto";

export async function set_tank_heat_info(kpa: number, temp: number, timeout: number) {
    return conn.request(addr.HEAT, heat.TANK_HEAT_INFO,
            new U16(kpa),
            new U16(temp),
            new U16(timeout)
        );
}

export interface TankHeatInfo {
    kpa: number,
    temp: number,
    timeout: number
}

export async function get_tank_heat_info() {

    const res = await conn.conn_query(addr.HEAT, heat.TANK_HEAT_INFO);
    const kpa = new U16();
    const temp = new U16();
    const timeout = new U16();
    res.parseResult(kpa, temp, timeout);
    const r: TankHeatInfo = {
        kpa: kpa.value,
        temp: temp.value,
        timeout: timeout.value
    }
    return r;
}

export async function set_reserve_heat_info(temp: number, timeout: number) {
    return await conn.request(
        addr.HEAT, heat.RESERVE_HEAT_INFO,
        new U16(temp), new U16(timeout)
    );
}

interface ReserveHeatInfo {
    temp: number,
    timeout: number,
}

export async function get_reserve_heat_info() {
    const res = await conn.conn_query(
        addr.HEAT, heat.RESERVE_HEAT_INFO
    );
    const temp = new U16();
    const timeout = new U16();
    res.parseResult(temp, timeout);
    const r: ReserveHeatInfo = {
        temp: temp.value,
        timeout: timeout.value
    }
    return r;
}

export async function set_draw_info(
    empty_weight: number, 
    reserve_draw_timeout: number,
    reserve_draw_temp: number,
    tank_draw_timeout: number) {
    
    return await conn.request(
        addr.HEAT, heat.DRAW_INFO,
        new U16(empty_weight),
        new U16(reserve_draw_timeout),
        new U16(reserve_draw_temp),
        new U16(tank_draw_timeout)
    );
}

export interface DrawInfo {
    empty_weight: number,
    reserve_draw_timeout: number,
    reserve_draw_temp: number,
    tank_draw_timeout: number
}

export async function get_draw_info() {
    const res = await conn.conn_query(
        addr.HEAT, heat.DRAW_INFO
    );
    const empty_weight = new U16();
    const reserve_draw_timeout = new U16();
    const reserve_draw_temp = new U16();
    const tank_draw_timeout = new U16();
    res.parseResult(
        empty_weight,
        reserve_draw_timeout,
        reserve_draw_temp,
        tank_draw_timeout
    );
    const r: DrawInfo = {
        empty_weight: empty_weight.value,
        reserve_draw_timeout: reserve_draw_timeout.value,
        reserve_draw_temp: reserve_draw_temp.value,
        tank_draw_timeout: tank_draw_timeout.value
    };
    return r;
}

export async function set_flow_info(count_1000ml: number) {
    return await conn.request(
        addr.HEAT, heat.FLOW_INFO,
        new U16(count_1000ml)
    );
}

export async function get_flow_info() {
    const res = await conn.conn_query(
        addr.HEAT, heat.FLOW_INFO
    );
    const count_1000ml = new U16();
    res.parseResult(count_1000ml);
    return count_1000ml.value;
}

export async function sw_ctrl(id: number, flag: boolean) {
    let v = 1;
    if (flag) {
        v = 0;
    }
    await conn.request(addr.HEAT, heat.SW_CTRL, 
        new U8(id),
        new U8(v)
    );
}

export async function heat_draw_ctrl(value: number) {
    return await conn.request(
        addr.HEAT, heat.DH_CTRL,
        new U8(value)
    );
}

export async function nozzle_ctrl(value: number) {
    return await conn.request(
        addr.HEAT, heat.NOZZLE,
        new U16(value)
    );
}

export async function drain_water(proxy: number, volume: number) {
    return await conn.request(
        addr.HEAT, heat.DRAIN_WATER,
        new U8(proxy), new U16(volume)
    );
}

export const TankProxy = {
    TANK1: 1,
    TANK2: 2,
    TANK1_2: 3,
    AUTO: 4,
};

export interface TankOption {
    water: number,
    steam: number,
}

export interface CleanOption {
    c: number,
    water: number,
    d: number,
    steam: number,
}

export interface CookingOption {
    k: number,
    pre_water: number,
    f: number,
    g: number,
    defroze: number,
    e: number,
    pour_water: number,
    h: number,
    mix_soup: number,
    i: number,
    clogging: number,
}

export async function clean(
    tank: TankOption, 
    clean: CleanOption
) {    
    return await conn.request(
        addr.HEAT, 
        heat.CLEAN,
        new U8(tank.water), new U8(tank.steam),
        new U16(clean.c), new U16(clean.water),
        new U16(clean.d), new U16(clean.steam)
    );
}

export async function cooking(
    tank: TankOption,
    cooking_option: CookingOption
) {
    return await conn.request(
        addr.HEAT,
        heat.COOKING,
        new U8(tank.water), new U8(tank.steam),
        new U16(cooking_option.k), new U16(cooking_option.pre_water),
        new U16(cooking_option.f), new U16(cooking_option.g), new U16(cooking_option.defroze),
        new U16(cooking_option.e), new U16(cooking_option.pour_water),
        new U16(cooking_option.h), new U16(cooking_option.mix_soup),
        new U16(cooking_option.i), new U16(cooking_option.clogging)
    );
}


